package com.unswift.cloud.adapter;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import com.unswift.cloud.core.CommonOperator;
import com.unswift.cloud.pojo.dao.AutoSqlDo;
import com.unswift.cloud.pojo.dao.sql.Sql;
import com.unswift.cloud.sql.AutoSql;
import com.unswift.utils.ClassUtils;
import com.unswift.utils.ObjectUtils;

@Api(value="自定义sql公共操作类", author="unswift", date="2023-04-16", version="1.0.0")
public class AutoSqlAdapter extends CommonOperator{
	
	@Autowired
	@ApiField("自定义公共sql")
	private AutoSql autoSql;

	@ApiMethod(value="在当前查询中增加查询的列", params = {@ApiField("查询对象"), @ApiField("查询的数据库列名"), @ApiField("列别名")})
	public <E extends AutoSqlDo> void addSelectColumn(E search, String columnName, String columnAlias) {
		Sql sql=search.getSql();
		if(ObjectUtils.isEmpty(sql)) {
			sql=Sql.createSql();
			search.setSql(sql);
		}
		sql.addSelect(columnName, columnAlias);
	}
	
	@ApiMethod(value="在当前查询中增加查询的列，可设置是否显示基础列", params = {@ApiField("查询对象"), @ApiField("查询的数据库列名"), @ApiField("列别名"), @ApiField("是否查询基础列，true：查询，false：不查询")})
	public <E extends AutoSqlDo> void addSelectColumn(E search, String columnName, String columnAlias, boolean baseSelect) {
		Sql sql=search.getSql();
		if(ObjectUtils.isEmpty(sql)) {
			sql=Sql.createSql();
			search.setSql(sql);
		}
		sql.setBaseSelect(baseSelect);
		sql.addSelect(columnName, columnAlias);
	}
	
	@ApiMethod(value="设置查询创建人的Sql", params = {@ApiField("查询对象"), @ApiField("创建人的属性名称，等于sql的别名")})
	public <E extends AutoSqlDo> void setCreateUserSql(E search, String fieldName) {
		Sql sql=search.getSql();
		if(ObjectUtils.isEmpty(sql)) {
			sql=Sql.createSql();
			search.setSql(sql);
		}
    	sql.addSelect(autoSql.findCreateUserNameSql(), fieldName);
    }
	
	@ApiMethod(value="设置from表的Sql", params = {@ApiField("查询对象"), @ApiField("表名"), @ApiField("表别名")})
	public <E extends AutoSqlDo> void addFromTable(E search, String tableName, String tableAlias) {
		Sql sql=search.getSql();
		if(ObjectUtils.isEmpty(sql)) {
			sql=Sql.createSql();
			search.setSql(sql);
		}
		sql.addFrom(tableName, tableAlias);
	}
	
	@ApiMethod(value="设置join表的Sql", params = {@ApiField("查询对象"), @ApiField("join表名"), @ApiField("join表别名"), @ApiField("join条件")})
	public <E extends AutoSqlDo> void addJoinTable(E search, String tableName, String tableAlias, String joinOnCondition) {
		Sql sql=search.getSql();
		if(ObjectUtils.isEmpty(sql)) {
			sql=Sql.createSql();
			search.setSql(sql);
		}
		sql.addFrom(tableName, tableAlias, Sql.FROM_JOIN, joinOnCondition);
	}
	
	@ApiMethod(value="更新语句增加更新字段", params = {@ApiField("更新对象"), @ApiField("更新字段"), @ApiField("更新值")})
    public <E extends AutoSqlDo> void addSet(E update, String columnName, String columnValue) {
    	Sql sql=update.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		update.setSql(sql);
    	}
    	sql.addSet(columnName, columnValue);
    }
    
    @ApiMethod(value="将某个属性转为like查询", params = {@ApiField("查询对象"), @ApiField("属性名称"), @ApiField("数据库列名列表，多字段同时模糊查询")})
    public <E extends AutoSqlDo> void setFieldToLike(E search, String fieldName, List<String> columnNameList) {
    	Object fieldValue=ClassUtils.get(search, fieldName);
    	if(ObjectUtils.isNotEmpty(fieldValue)) {//如果不为空，则转为like
    		Sql sql=search.getSql();
    		if(ObjectUtils.isEmpty(sql)) {
    			sql=Sql.createSql();
    			search.setSql(sql);
    		}
    		ClassUtils.set(search, fieldName, null);//清空当前属性的查询条件
    		int index=0, length=columnNameList.size();
    		for (String columnName : columnNameList) {
				if(length==1) {
					sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_LIKE, Sql.sqlValue("%"+fieldValue+"%"));//设置like查询
				}else {
					if(index==0) {
						sql.addWhere(Sql.LOGIC_AND, true, false, columnName, Sql.COMPARE_LIKE, Sql.sqlValue("%"+fieldValue+"%"));//设置like查询
					}else if(index==length-1) {
						sql.addWhere(Sql.LOGIC_OR, false, true, columnName, Sql.COMPARE_LIKE, Sql.sqlValue("%"+fieldValue+"%"));//设置like查询
					}else {
						sql.addWhere(Sql.LOGIC_OR, columnName, Sql.COMPARE_LIKE, Sql.sqlValue("%"+fieldValue+"%"));//设置like查询
					}
				}
				index++;
			}
    	}
    }
    
    @ApiMethod(value="查询语句增加排序", params = {@ApiField("查询对象"), @ApiField("排序字段"), @ApiField("顺序或倒叙")})
    public <E extends AutoSqlDo> void addOrderBy(E search, String orderByField, String ascOrDesc) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addOrderBy(orderByField, ascOrDesc);
    }
    
    @ApiMethod(value="查询语句in查询", params = {@ApiField("查询对象"), @ApiField("字段名称"), @ApiField("in的列表值")})
    public <E extends AutoSqlDo> void addWhereInList(E search, String columnName, List<?> columnValueList) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	columnValueList=columnValueList.stream().map(v -> Sql.sqlValue(v)).collect(Collectors.toList());
    	Object[] array=columnValueList.toArray(new Object[columnValueList.size()]);
    	sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_IN, array);
    	
    }
    
    @ApiMethod(value="查询语句in查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("in的列表值")})
    public <E extends AutoSqlDo> void addWhereIn(E search, String columnName, String columnValue) {
    	if(ObjectUtils.isEmpty(columnValue)) {
    		return ;
    	}
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_IN, columnValue);
    	
    }
	
    @ApiMethod(value="查询语句BETWEEN AND查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("开始值"), @ApiField("结束值"), @ApiField("日期格式")})
    public <E extends AutoSqlDo> void addWhereBetweenList(E search, String columnName, Date startTime, Date endTime, String format) {
    	if(ObjectUtils.isNotEmpty(startTime) && ObjectUtils.isNotEmpty(endTime)) {
    		Sql sql=search.getSql();
    		if(ObjectUtils.isNull(sql)) {
    			sql=Sql.createSql();
    			search.setSql(sql);
    		}
    		sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_BETWEEN, Sql.sqlValue(startTime, format), Sql.sqlValue(endTime, format));
    	}
    }
    
    @ApiMethod(value="查询语句=查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("列值"), @ApiField("列值格式")})
    public <E extends AutoSqlDo> void addWhereEquals(E search, String columnName, Object columnValue, String format) {
    	if(ObjectUtils.isEmpty(columnValue)) {
    		return ;
    	}
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_EQUAL, Sql.sqlValue(columnValue, format));
    }
    
    @ApiMethod(value="查询语句=查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("列值"), @ApiField("列值格式")})
    public <E extends AutoSqlDo> void addWhereGt(E search, String columnName, Object columnValue, String format) {
    	if(ObjectUtils.isEmpty(columnValue)) {
    		return ;
    	}
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_GREATER_EQUAL, Sql.sqlValue(columnValue, format));
    }
    
    @ApiMethod(value="查询语句IS NULL或IS NOT NULL查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("IS NULL或者IS NOT NULl,true表示IS NULL,false表示IS NOT NULL")})
    public <E extends AutoSqlDo> void addWhereNull(E search, String columnName, boolean nullOrNotNull) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addWhere(Sql.LOGIC_AND, columnName, nullOrNotNull?Sql.COMPARE_IS:Sql.COMPARE_IS_NOT, "NULL");
    }
    
    @ApiMethod(value="查询语句<>查询", params = {@ApiField("查询对象"), @ApiField("列名称"), @ApiField("列值"), @ApiField("列值格式")})
    public <E extends AutoSqlDo> void addWhereNotEquals(E search, String columnName, Object columnValue, String format) {
    	if(ObjectUtils.isEmpty(columnValue)) {
    		return ;
    	}
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.addWhere(Sql.LOGIC_AND, columnName, Sql.COMPARE_NOT_EQUAL, Sql.sqlValue(columnValue, format));
    }
    
    @ApiMethod(value="设置是否查询基础select字段", params = {@ApiField("查询条件"), @ApiField("是否查询基础字段{true：查询，false：不查询}")})
    public <E extends AutoSqlDo> void setBaseSelect(E search, boolean baseSelect) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.setBaseSelect(baseSelect);
    }
    
    @ApiMethod(value="设置是否查询本表", params = {@ApiField("查询条件"), @ApiField("是否查询本表{true：查询，false：不查询}")})
    public <E extends AutoSqlDo> void setBaseFrom(E search, boolean baseFrom) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.setBaseFrom(baseFrom);
    }
    
    @ApiMethod(value="设置是否查询基础where字段", params = {@ApiField("查询条件"), @ApiField("是否查询条件查询{true：查询，false：不查询}")})
    public <E extends AutoSqlDo> void setBaseWhere(E search, boolean baseWhere) {
    	Sql sql=search.getSql();
    	if(ObjectUtils.isNull(sql)) {
    		sql=Sql.createSql();
    		search.setSql(sql);
    	}
    	sql.setBaseWhere(baseWhere);
    }
}
